package com.lwl.blue.seven.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.additional.query.impl.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lwl.blue.commont.base.JsonResult;
import com.lwl.blue.commont.base.PageResult;
import com.lwl.blue.commont.base.PageParam;
import com.lwl.blue.seven.entity.Contract7;
import com.lwl.blue.seven.entity.ContractItem7;
import com.lwl.blue.seven.dao.Contract7Dao;
import com.lwl.blue.seven.dao.ContractItem7Dao;
import com.lwl.blue.seven.service.Contract7Service;
import com.lwl.blue.seven.dto.*;
import com.lwl.blue.seven.constants.ContractStatus;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.Optional;

/**
 * 采购合同主表(Contract7)表服务实现类
 *
 * @author makejava
 * @since 2025-09-17 14:45:32
 */
@Service("contract7Service")
public class Contract7ServiceImpl extends ServiceImpl<Contract7Dao, Contract7> implements Contract7Service {

    @Resource
    private Contract7Dao contract7Dao;

    @Resource
    private ContractItem7Dao contractItem7Dao;

    @Override
    public PageResult<Contract7ListVO> queryContractList(PageParam<Contract7QueryDTO> pageParam, Long currentUserId) {
        Contract7QueryDTO queryDTO = pageParam.getParam();
        if (queryDTO == null) {
            queryDTO = new Contract7QueryDTO();
        }

        // 创建分页对象
        Page<Contract7> page = new Page<>(pageParam.getPageNum(), pageParam.getPageSize());

        // 构造查询条件
        LambdaQueryWrapper<Contract7> queryWrapper = buildQueryWrapper(queryDTO);

        // 执行分页查询
        IPage<Contract7> resultPage = this.page(page, queryWrapper);

        // 转换为 VO 对象
        List<Contract7ListVO> voList = convertToVOList(resultPage.getRecords(), currentUserId);

        // 返回结果
        PageResult<Contract7ListVO> result = new PageResult<>();
        result.success(resultPage.getTotal(), voList);
        return result;
    }

    @Override
    public Contract7DetailDTO getContractDetail(Long contractId, Long currentUserId) {
        Contract7 contract = contract7Dao.queryById(contractId);
        if (contract == null || contract.getIsDeleted() == 1) {
            return null;
        }

        Contract7DetailDTO detailDTO = new Contract7DetailDTO();
        BeanUtils.copyProperties(contract, detailDTO);
        detailDTO.setStatusName(ContractStatus.getNameByCode(contract.getStatus()));

        // 获取商品明细
        List<Contract7DetailItemDTO> items = contractItem7Dao.queryItemsByContractId(contractId);
        detailDTO.setItemList(items);

        return detailDTO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<Long> createContract(Contract7CreateDTO createDTO, Long currentUserId) {
        // 验证合同编号唯一性
        if (contract7Dao.checkContractNumberExists(createDTO.getContractNumber(), null) > 0) {
            return new JsonResult<Long>().error("合同编号已存在");
        }

        // 验证商品明细
        if (CollectionUtils.isEmpty(createDTO.getItemList())) {
            return new JsonResult<Long>().error("商品明细不能为空");
        }

        // 计算总金额（使用BigDecimal）
        BigDecimal totalAmount = calculateTotalAmount(createDTO.getItemList());

        // 创建合同主表
        Contract7 contract = new Contract7();
        BeanUtils.copyProperties(createDTO, contract);
        contract.setStatus(ContractStatus.DRAFT.getCode());
        contract.setCreateUserId(currentUserId);
        contract.setCreateTime(new Date());
        contract.setUpdateUserId(currentUserId);
        contract.setUpdateTime(new Date());
        contract.setTotalAmount(totalAmount);
        contract.setVersion(1);
        contract.setIsDeleted(0);
        contract.setRedFlag(0);

        int result = contract7Dao.insert(contract);
        if (result <= 0) {
            return new JsonResult<Long>().error("创建合同失败");
        }

        // 保存商品明细
        JsonResult<Void> itemResult = saveContractItems(contract.getContractId(), createDTO.getItemList());
        if (!itemResult.isSuccess()) {
            throw new RuntimeException("保存商品明细失败：" + itemResult.getMessage());
        }

        return new JsonResult<Long>().success(contract.getContractId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<Void> updateContract(Long contractId, Contract7CreateDTO createDTO, Long currentUserId) {
        Contract7 contract = contract7Dao.queryById(contractId);
        if (contract == null || contract.getIsDeleted() == 1) {
            return new JsonResult<Void>().error("合同不存在");
        }

        // 权限检查：只有创建人在草稿或驳回状态下才能编辑
        if (!currentUserId.equals(contract.getCreateUserId())) {
            return new JsonResult<Void>().error("无权限编辑此合同");
        }

        if (!ContractStatus.canEdit(contract.getStatus())) {
            return new JsonResult<Void>().error("当前状态不允许编辑");
        }

        // 验证合同编号唯一性
        if (contract7Dao.checkContractNumberExists(createDTO.getContractNumber(), contractId) > 0) {
            return new JsonResult<Void>().error("合同编号已存在");
        }

        // 计算总金额（使用BigDecimal）
        BigDecimal totalAmount = calculateTotalAmount(createDTO.getItemList());

        // 更新合同主表
        BeanUtils.copyProperties(createDTO, contract);
        contract.setTotalAmount(totalAmount);
        contract.setUpdateUserId(currentUserId);
        contract.setUpdateTime(new Date());

        int result = contract7Dao.update(contract);
        if (result <= 0) {
            return new JsonResult<Void>().error("更新合同失败");
        }

        // 删除原有明细，重新保存
        contractItem7Dao.deleteByContractId(contractId);

        // 保存商品明细
        JsonResult<Void> itemResult = saveContractItems(contractId, createDTO.getItemList());
        if (!itemResult.isSuccess()) {
            throw new RuntimeException("保存商品明细失败：" +  itemResult.getMessage());
        }

        return new JsonResult<Void>().success("ok");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<Void> deleteContract(Long contractId, Long currentUserId) {
        Contract7 contract = contract7Dao.queryById(contractId);
        if (contract == null || contract.getIsDeleted() == 1) {
            return new JsonResult<Void>().error("合同不存在");
        }

        // 权限检查：只有创建人在草稿状态下才能删除
        if (!currentUserId.equals(contract.getCreateUserId())) {
            return new JsonResult<Void>().error("无权限删除此合同");
        }

        if (!ContractStatus.canDelete(contract.getStatus())) {
            return new JsonResult<Void>().error("当前状态不允许删除");
        }

        int result = contract7Dao.softDeleteById(contractId);
        if (result <= 0) {
            return new JsonResult<Void>().error("删除合同失败");
        }

        return new JsonResult<Void>().success("ok");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<Void> batchDeleteContract(List<Long> contractIds, Long currentUserId) {
        if (CollectionUtils.isEmpty(contractIds)) {
            return new JsonResult<Void>().error("请选择要删除的合同");
        }

        int result = contract7Dao.batchSoftDelete(contractIds, currentUserId);

        return new JsonResult<Void>().success("成功删除 " + result + " 个合同");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<Void> submitContract(Long contractId, Long currentUserId) {
        Contract7 contract = contract7Dao.queryById(contractId);
        if (contract == null || contract.getIsDeleted() == 1) {
            return new JsonResult<Void>().error("合同不存在");
        }

        // 权限检查：只有创建人在草稿状态下才能提交
        if (!currentUserId.equals(contract.getCreateUserId())) {
            return new JsonResult<Void>().error("无权限提交此合同");
        }

        if (!ContractStatus.canSubmit(contract.getStatus())) {
            return new JsonResult<Void>().error("当前状态不允许提交");
        }

        int result = contract7Dao.updateContractStatus(contractId, ContractStatus.PENDING_AUDIT.getCode(), null);
        if (result <= 0) {
            return new JsonResult<Void>().error("提交失败");
        }

        return new JsonResult<Void>().success("提交成功");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<Void> approveContract(Long contractId, Long currentUserId) {
        Contract7 contract = contract7Dao.queryById(contractId);
        if (contract == null || contract.getIsDeleted() == 1) {
            return new JsonResult<Void>().error("合同不存在");
        }

        if (!ContractStatus.canAudit(contract.getStatus())) {
            return new JsonResult<Void>().error("当前状态不允许审核");
        }

        int result = contract7Dao.updateContractStatus(contractId, ContractStatus.EXECUTING.getCode(), currentUserId);
        if (result <= 0) {
            return new JsonResult<Void>().error("审核失败");
        }

        return new JsonResult<Void>().success("审核通过");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<Void> rejectContract(Long contractId, Long currentUserId) {
        Contract7 contract = contract7Dao.queryById(contractId);
        if (contract == null || contract.getIsDeleted() == 1) {
            return new JsonResult<Void>().error("合同不存在");
        }

        if (!ContractStatus.canAudit(contract.getStatus())) {
            return new JsonResult<Void>().error("当前状态不允许审核");
        }

        int result = contract7Dao.updateContractStatus(contractId, ContractStatus.REJECTED.getCode(), currentUserId);
        if (result <= 0) {
            return new JsonResult<Void>().error("驳回失败");
        }

        return new JsonResult<Void>().success("已驳回");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<Void> completeContract(Long contractId, Long currentUserId) {
        Contract7 contract = contract7Dao.queryById(contractId);
        if (contract == null || contract.getIsDeleted() == 1) {
            return new JsonResult<Void>().error("合同不存在");
        }

        // 检查是否处于可完成状态
        if (!ContractStatus.canComplete(contract.getStatus())) {
            return new JsonResult<Void>().error("当前状态不允许完成合同");
        }

        // 执行状态更新
        int result = contract7Dao.updateContractStatus(contractId, ContractStatus.COMPLETED.getCode(), currentUserId);
        if (result <= 0) {
            return new JsonResult<Void>().error("完成合同失败");
        }

        return new JsonResult<Void>().success("合同已完成");
    }

    @Override
    public List<Contract7DetailItemDTO> getContractItems(Long contractId) {
        return contractItem7Dao.queryItemsByContractId(contractId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult<Void> saveContractItems(Long contractId, List<Contract7CreateItemDTO> items) {
        if (CollectionUtils.isEmpty(items)) {
            return new JsonResult<Void>().error("商品明细不能为空");
        }

        List<ContractItem7> itemEntities = new ArrayList<>();
        for (Contract7CreateItemDTO itemDTO : items) {
            ContractItem7 item = new ContractItem7();
            item.setContractId(contractId);
            item.setProductId(itemDTO.getProductId());
            item.setProductName(itemDTO.getProductName());
            item.setProductCode(itemDTO.getProductCode());
            item.setProductUnit(itemDTO.getProductUnit());
            item.setProductPrice(itemDTO.getProductPrice());
            item.setProductQuantity(itemDTO.getProductQuantity());

            BigDecimal price = Optional.ofNullable(itemDTO.getProductPrice()).orElse(BigDecimal.ZERO);
            BigDecimal quantity = Optional.ofNullable(itemDTO.getProductQuantity()).orElse(BigDecimal.ZERO);
            item.setContractAmount(price.multiply(quantity).setScale(6, RoundingMode.HALF_UP));

            item.setDeliveryLocation(itemDTO.getDeliveryLocation());
            item.setDeliveryDate(itemDTO.getDeliveryDate());
            item.setCreateTime(new Date());
            item.setUpdateTime(new Date());

            itemEntities.add(item);
        }

        int result = contractItem7Dao.batchInsert(itemEntities);
        if (result <= 0) {
            return new JsonResult<Void>().error("保存商品明细失败");
        }

        return new JsonResult<Void>().success("ok");
    }

    /**
     * 计算总金额（修复：使用BigDecimal避免类型转换问题）
     */
    private BigDecimal calculateTotalAmount(List<Contract7CreateItemDTO> items) {
        BigDecimal total = BigDecimal.ZERO;
        for (Contract7CreateItemDTO item : items) {
            // 获取单价和数量，为空则默认为0
            BigDecimal price = Optional.ofNullable(item.getProductPrice()).orElse(BigDecimal.ZERO);
            BigDecimal quantity = Optional.ofNullable(item.getProductQuantity()).orElse(BigDecimal.ZERO);

            // 计算单项金额并累加（保留6位小数，四舍五入）
            BigDecimal itemAmount = price.multiply(quantity).setScale(6, RoundingMode.HALF_UP);
            total = total.add(itemAmount);
        }
        return total;
    }

    /**
     * 转换 Entity 列表为 VO 列表
     */
    private List<Contract7ListVO> convertToVOList(List<Contract7> contractList, Long currentUserId) {
        List<Contract7ListVO> voList = new ArrayList<>();
        
        for (Contract7 contract : contractList) {
            Contract7ListVO vo = new Contract7ListVO();
            
            // 基本信息映射
            vo.setContractId(contract.getContractId());
            vo.setContractNumber(contract.getContractNumber());
            vo.setContractName(contract.getContractName());
            vo.setSupplierId(contract.getSupplierId());
            vo.setTotalAmount(contract.getTotalAmount());
            vo.setCreateUserId(contract.getCreateUserId());
            vo.setCreateTime(contract.getCreateTime());
            vo.setEffectiveDate(contract.getEffectiveDate());
            vo.setExpiryDate(contract.getExpiryDate());
            vo.setStatus(contract.getStatus());
            
            // 设置状态名称
            vo.setStatusName(ContractStatus.getNameByCode(contract.getStatus()));
            
            // 设置权限标识
            setPermissionFlags(vo, currentUserId);
            
            voList.add(vo);
        }
        
        return voList;
    }

    /**
     * 构建查询条件包装器
     * 
     * @param queryDTO 查询参数
     * @return 查询条件包装器
     */
    private LambdaQueryWrapper<Contract7> buildQueryWrapper(Contract7QueryDTO queryDTO) {
        LambdaQueryWrapper<Contract7> queryWrapper = new LambdaQueryWrapper<>();
        
        // 基本条件：未删除
        queryWrapper.eq(Contract7::getIsDeleted, 0);
        
        // 关键词搜索：合同编号、合同名称
        if (queryDTO.getKeyword() != null && !queryDTO.getKeyword().trim().isEmpty()) {
            String keyword = queryDTO.getKeyword().trim();
            queryWrapper.and(wrapper -> wrapper
                .like(Contract7::getContractNumber, keyword)
                .or()
                .like(Contract7::getContractName, keyword)
            );
        }
        
        // 供应商筛选
        if (queryDTO.getSupplierId() != null) {
            queryWrapper.eq(Contract7::getSupplierId, queryDTO.getSupplierId());
        }
        
        // 状态筛选
        if (queryDTO.getStatus() != null) {
            queryWrapper.eq(Contract7::getStatus, queryDTO.getStatus());
        }
        
        // 交易类型筛选
        if (queryDTO.getTransactionType() != null && !queryDTO.getTransactionType().isEmpty()) {
            queryWrapper.eq(Contract7::getTransactionType, queryDTO.getTransactionType());
        }
        
        // 生效日期范围
        if (queryDTO.getEffectiveDateStart() != null) {
            queryWrapper.ge(Contract7::getEffectiveDate, queryDTO.getEffectiveDateStart());
        }
        if (queryDTO.getEffectiveDateEnd() != null) {
            queryWrapper.le(Contract7::getEffectiveDate, queryDTO.getEffectiveDateEnd());
        }
        
        // 失效日期范围
        if (queryDTO.getExpiryDateStart() != null) {
            queryWrapper.ge(Contract7::getExpiryDate, queryDTO.getExpiryDateStart());
        }
        if (queryDTO.getExpiryDateEnd() != null) {
            queryWrapper.le(Contract7::getExpiryDate, queryDTO.getExpiryDateEnd());
        }
        
        // 创建时间范围
        if (queryDTO.getCreateTimeStart() != null) {
            queryWrapper.ge(Contract7::getCreateTime, queryDTO.getCreateTimeStart());
        }
        if (queryDTO.getCreateTimeEnd() != null) {
            queryWrapper.le(Contract7::getCreateTime, queryDTO.getCreateTimeEnd());
        }
        
        // 按创建时间降序排列
        queryWrapper.orderByDesc(Contract7::getCreateTime);
        
        return queryWrapper;
    }

    /**
     * 设置权限标识
     */
    private void setPermissionFlags(Contract7ListVO vo, Long currentUserId) {
        boolean isCreator = currentUserId.equals(vo.getCreateUserId());

        vo.setCanEdit(isCreator && ContractStatus.canEdit(vo.getStatus()));
        vo.setCanDelete(isCreator && ContractStatus.canDelete(vo.getStatus()));
        vo.setCanSubmit(isCreator && ContractStatus.canSubmit(vo.getStatus()));
        vo.setCanAudit(!isCreator && ContractStatus.canAudit(vo.getStatus()));
    }
}
